/*
 * Author: William Kim
 * Date: November 13, 2012
 * 
 * JUnit test class for FileIO.FileManager class.
 */

package Test;

import static org.junit.Assert.*;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.junit.Before;
import org.junit.Test;

import FileIO.FileManager;
import Model.Conference;
import Model.Conference.Role;
import Model.Paper;
import Model.User;

public class TestFileManager
{
  private static final User PAUL = new User("Paul Schultz", "PaulS",
      "P@fake.com");
  private static final User WILLIAM = new User("William Kim", "WilliamK",
      "W@fake.com");
  private static final User IRVING = new User("Irving Estrera", "IrvingE",
      "I@fake.com");
  private static final User NATHAN = new User("Nathan Judkins", "NathanJ",
      "N@fake.com");

  private static final String CONFERENCE_NAME = "Smart Software Development";
  private static final Date DEADLINE_DATE = new Date(113, 1, 20);
  private static final File MANUSCRIPT_FILE = new File(
      "data/PaperSubmissionSheet.docx");
  private static final File RECOMMENDATION_FILE = new File(
      "data/RecommendationForm.docx");
  private static final File REVIEW_FILE = new File("data/ReviewForm.docx");

  private static Set<User> test_user_set;
  private static Paper test_paper;

  private static Conference test_conference;

  @Before
  public void setUp() throws Exception
  {
    test_user_set = new HashSet<User>();
    test_user_set.add(IRVING);
    test_user_set.add(NATHAN);
    test_user_set.add(PAUL);
    test_user_set.add(WILLIAM);

    test_paper = new Paper("The Joys of Paper Prototyping", WILLIAM, IRVING,
        MANUSCRIPT_FILE);

    test_paper.editReview(NATHAN, REVIEW_FILE);
    test_paper.editRecommendation(RECOMMENDATION_FILE);
    test_paper.editDecision(1);

    final List<Role> pc_role = new ArrayList<Role>();
    pc_role.add(Role.PROGRAM_CHAIR);
    final List<Role> spc_role = new ArrayList<Role>();
    spc_role.add(Role.REVIEWER);
    spc_role.add(Role.SUB_CHAIR);
    final List<Role> reviewer_role = new ArrayList<Role>();
    reviewer_role.add(Role.REVIEWER);
    final List<Role> author_role = new ArrayList<Role>();
    author_role.add(Role.AUTHOR);

    Map<User, List<Role>> role_map = new HashMap<User, List<Role>>();

    role_map.put(PAUL, pc_role);
    role_map.put(IRVING, spc_role);
    role_map.put(NATHAN, reviewer_role);
    role_map.put(WILLIAM, author_role);

    test_conference = new Conference(CONFERENCE_NAME, PAUL, role_map,
        DEADLINE_DATE);

    test_conference.addPaper(test_paper);
  }

  /*
   * Tests the data that gets loaded from the user data saved files. The files
   * are first saved using the test data from the constant fields and
   * initialized data in the setUp() method.
   */
  @Test
  public void testSaveLoadUsers()
  {
    FileManager.saveUsers(test_user_set);

    Set<User> user_list = FileManager.loadUsers();
    // for (User u : user_list)
    // {
    // System.out.println(u);
    // }

    assertEquals(user_list, test_user_set);
  }

  /*
   * Tests the data that gets loaded from the conference data saved files. The
   * files are first saved using the test data from the constant fields and
   * initialized data in the setUp() method.
   */
  @Test
  public void testSaveLoadConferences()
  {
    FileManager.saveUsers(test_user_set);

    FileManager.loadUsers();

    final List<Conference> conferences = new ArrayList<Conference>();
    conferences.add(test_conference);
    FileManager.saveConferences(conferences);

    final Conference test = (FileManager.loadConferences()).get(0);

    assertEquals("test pc failed", test.programChair(), PAUL);
    assertEquals("test conf name failed", test.conferenceName(),
        CONFERENCE_NAME);
    assertEquals("test users set failed", test.users(), test_user_set);
    assertEquals("test spc failed", test.subProgramChairs().get(0), IRVING);
    assertEquals("test date failed", test.getDeadline(), DEADLINE_DATE);
    assertTrue("test role1 failed",
        test.getRoles(IRVING).contains(Conference.Role.REVIEWER));
    assertTrue("test role2 failed",
        test.getRoles(IRVING).contains(Conference.Role.SUB_CHAIR));
    // System.out.println(test.getDeadline());

  }

  /*
   * Tests the data that gets loaded from the paper data saved files. The files
   * are first saved using the test data from the constant fields and
   * initialized data in the setUp() method.
   */
  @Test
  public void testSaveLoadPapers()
  {
    FileManager.saveUsers(test_user_set);

    FileManager.loadUsers();

    final List<Conference> conferences = new ArrayList<Conference>();
    conferences.add(test_conference);
    FileManager.saveConferences(conferences);

    final Conference test = (FileManager.loadConferences()).get(0);


    assertEquals("test whole Paper failed", test.getPapersByAuthor(WILLIAM)
        .get(0), test_paper);

    assertEquals("test author failed", test
        .getPapersAssignedToSubChairs(IRVING).get(0).getAuthor(), WILLIAM);
    assertEquals("test paper spc failed",
        test.getPapersAssignedToSubChairs(IRVING).get(0).getSubprogramChair(),
        IRVING);
    assertEquals("test Manuscript File failed", test
        .getPapersAssignedToSubChairs(IRVING).get(0).getManuscript().getName(),
        MANUSCRIPT_FILE.getName());
    assertEquals("test Recommendation File failed", test
        .getPapersAssignedToSubChairs(IRVING).get(0).getRecommendation()
        .getName(), RECOMMENDATION_FILE.getName());
    assertEquals("test Review File failed",
        test.getPapersAssignedToReviewers(NATHAN).get(0)
            .getMyReviewAssociation().get(NATHAN).getName(),
        REVIEW_FILE.getName());
    assertEquals("test acceptance status failed", test.getSubmittedPapers()
        .get(0).getDecision(), 1);
  }

}
